using System;
using System.Linq.Expressions;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using FluentSilverlight.Utility.Reflection;

namespace FluentSilverlight.Expressions.Buttons
{
    public class CheckBoxExpression<TModel> : ToggleButtonExpression<CheckBoxExpression<TModel>, TModel, CheckBox>
        where TModel : class
    {
        private readonly Accessor valueAccessor;
        private BindingMode bindingMode = BindingMode.TwoWay;
        private string content;

        public CheckBoxExpression(TModel model)
            : this(model, string.Format("TextBlock_{0}", Guid.NewGuid()))
        {
        }

        public CheckBoxExpression(TModel model, string name) : base(model, name)
        {
            isCheckedBindingMode = BindingMode.TwoWay;
        }

        public CheckBoxExpression(TModel model, Expression<Func<TModel, object>> expression)
            : base(model)
        {
            valueAccessor = ReflectionHelper.GetAccessor(expression);
        }

        public BindModeExpression<CheckBoxExpression<TModel>> BindMode
        {
            get { return new BindModeExpression<CheckBoxExpression<TModel>>(this, b => bindingMode = b); }
        }

        public CheckBoxExpression<TModel> Content(string value)
        {
            content = value;
            return thisInstance();
        }

        protected override CheckBoxExpression<TModel> thisInstance()
        {
            return this;
        }

        protected override void BuildUp(CheckBox item)
        {
            base.BuildUp(item);

            item.Content = content;

            if (valueAccessor != null)
            {
                var binding = new Binding(valueAccessor.Name) { Mode = bindingMode };
                item.SetBinding(ToggleButton.IsCheckedProperty, binding);
            }
        }

        public static implicit operator CheckBox(CheckBoxExpression<TModel> expression)
        {
            var item = new CheckBox();
            expression.BuildUp(item);
            return item;
        }

        protected override object GetCommandParameter(CheckBox item)
        {
            return item.IsChecked;
        }
    }
}